<?php

namespace Core\Common;

use app\config\Db;
use app\config\Redis;
use app\config\Token;
use App\Controller\Example\BaseExample;
use Core\Enums\ErrorEnum;
use Core\Result\Result;

class Common
{
    /**
     * sql对象赋值
     * @return object
     */
    public static function assemble($data){
        $object = new CommonClass();
        foreach ($data as $item => $val){
            $object->$item = $val;
        }
        return $object;
    }
    //翻页通用
    public static function identical($data){
        $assemble = Common::assemble($data);
        if($assemble->page ==null)$assemble->page=1;
        if($assemble->limit ==null)$assemble->limit=10;
        $assemble->pageStart =$assemble->limit*($assemble->page-1);
        return $assemble;
    }
    /**
     * curl请求
     * @return string
     */
    public function sendCurl($url,$params=false,$ispost=0){
        $httpInfo = array();
        $ch = curl_init();
        curl_setopt( $ch, CURLOPT_HTTP_VERSION , CURL_HTTP_VERSION_1_1 );
        curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT , 3);
        curl_setopt( $ch, CURLOPT_TIMEOUT , 8);
        curl_setopt( $ch, CURLOPT_RETURNTRANSFER , true );
        if ($params) {
            if (is_array($params)) {
                $paramsString = http_build_query($params);
            } else {
                $paramsString = $params;
            }
        } else {
            $paramsString = "";
        }
        if( $ispost )
        {
            curl_setopt( $ch , CURLOPT_POST , true );
            curl_setopt( $ch , CURLOPT_POSTFIELDS , $paramsString);
            curl_setopt( $ch , CURLOPT_URL , $url );
        }
        else
        {
            if($paramsString ){
                curl_setopt( $ch , CURLOPT_URL , $url.'?'.$paramsString);
            }else{
                curl_setopt( $ch , CURLOPT_URL , $url);
            }
        }
        $response = curl_exec( $ch );
        if ($response === FALSE) {
            //echo "cURL Error: " . curl_error($ch);
            return false;
        }
        $httpCode = curl_getinfo( $ch , CURLINFO_HTTP_CODE );
        $httpInfo = array_merge( $httpInfo , curl_getinfo( $ch ) );
        curl_close( $ch );
        return $response;
    }
    /** TODO 获取user_id
     * 获取post参数
     * @return array|int
     */
    public static function getUser_id($data){
        if(empty($data)){
            return '';
        }else{
            return $data["userInfo"]["user_id"];
        }
    }
    /** TODO 获取用户token
     * 获取post参数
     * @return
     */
    public static function getUserId($a)
    {
        if(empty($a)){
            header("HTTP/1.0 404 Not Found");
            echo "404 - 页面未找到";
            exit;
        }
        $userToken = self::getToken();
        if (!in_array($a, self::api_nologin())) {
            if (!$userToken){
                Result::error(ErrorEnum::ACCOUNTINVALID,401);
            }
            $userData = Token::verify($userToken);
            $cache = new Redis();
            $cacheUserToken = $cache->get("{$userData['user_id']}_token");
            if (empty($cacheUserToken)){
                Result::error("登录过期，请重新登录",401);
            }
            if ($userToken !== $cacheUserToken)
            {
                Result::error("账号已在别处登录，请重新登录",401);
            }
            self::userStatus($userData['user_id'], 1);//判断用户状态
            return $userData;
        }
        $isTokenInfo = ['getGeneralCode','goodsInfo'];
        if (in_array($a, $isTokenInfo) && !empty($userToken)) {
            $userData = Token::verify($userToken);
            return $userData;
        }
    }
    public static function userStatus($userId, $is_login = 1)
    {
        $db = new Db();
        $UserInfo = $db->find("select account_non_expired,account_non_locked,credentials_non_expired,enable from user_authentication where id = $userId");
        if ($is_login == 1) {
            if ($UserInfo['account_non_expired'] == 0){
                Result::error("账号已过期",401);
            }
            if ($UserInfo['account_non_locked'] == 0){
                Result::error("账号已锁定",401);
            }
            if ($UserInfo['enable'] == 0 || $UserInfo['credentials_non_expired'] == 0){
                Result::error("账号已注销活或已过期",401);
            }
        }
    }
    public static function getToken()
    {
        if (function_exists('apache_request_headers') && $result = apache_request_headers()) {
            $header = $result;
        } else {
            // 没有 apache_request_headers函数替代方法
            $header = [];
            $server = $_SERVER;
            foreach ($server as $key => $val) {
                if (0 === strpos($key, 'HTTP_')) {
                    $key = str_replace('_', '-', strtolower(substr($key, 5)));
                    $header[$key] = $val;
                }
            }
            if (isset($server['CONTENT_TYPE'])) {
                $header['content-type'] = $server['CONTENT_TYPE'];
            }
            if (isset($server['CONTENT_LENGTH'])) {
                $header['content-length'] = $server['CONTENT_LENGTH'];
            }
        }
        if (isset($header['Apitoken']) && !empty($header['Apitoken'])) {
            return $header['Apitoken'];
        }
        return false;
    }
    /**
     * 获取post参数
     * @return array
     */
    public static function getPost(){
        $response = json_decode(file_get_contents('php://input'), true);
        if(empty($response)){
            $response = $_REQUEST;
        }
        $data = [];
        foreach($response as $k=>$v)
        {
            if($k == "token" || $k == "resource"){
                $data[$k] =$v;
            }else{
                $data[$k] = Common::filter($v);
            }
        }
        if(empty($data["page"]) || !is_numeric($data["limit"]) || $data["limit"] <= 0 || $data["limit"] >= 100){
            $data["limit"] = 20;
        }
        if (empty($data["page"]) || !is_numeric($data["page"]) || $data["page"] <= 0) {
            $data["page"] = 1;
        }
        $data["page"] = ($data["page"] - 1) * $data["limit"];
        return $data;
    }
    /**
     * 错误返回（抛出异常）
     *
     * @param string $msg 错误提示
     * @param int $code 错误码
     *
     * @return Exception
     */
    public static function exception($msg = '操作失败', $code = 500)
    {
        throw new \Exception($msg, $code);
    }
    /**
     * 获取配置文件 TODO
     * @param $name
     * @return mixed
     */
    public static function config($name)
    {
        return include(__DIR__."./../../app/config/$name.php");
    }
    /**
     * 判断不登录操作函数
     * @return array
     */
    public static function api_nologin(){
        return [
            'reg', //注册
            'agreement', //协议
            'login', //登录
            'smsCode', //发送短信验证码
            'forgotPwd', //忘记密码
            'banner', //首页轮播图
            'homeActiveList',//首页活动
            'homeSectionList',//专区信息
            'activeGoodsList',//活动商品
            'homeNotice',//首页公告
            'noticeList',//首页公告列表
            'register',//用户注册
            'forgotPassword',//忘记密码
            'sendCode',//发送验证码
            'goodsCategory',//商品分类
            'goodsList',//商品列表
            'goodsInfo',//商品详情
            'skuSearch',//sku筛选
            'AppUpdate',//app更新
            'weatherInformation',//首页天气获取
            'category',//商品分类
            'newNotice',//最新公告
            'newAdvertising',//最新广告
            'goodsAllComments',//查看商品所有评论
            'wechatPayCallback',//微信支付回调
            'rechargePayCallback',//会员充值回调
            'scanPayCallback',//会员扫码付回调
            'carousel',//轮播图
            'shopActiveList',//商城活动
            'aftersalesRefund',//后台退款接口
        ];
    }
    /**
     * 参数过滤
     * @return string
     */
    private static function filter($data){
        /*$data=str_replace("#","",$data);
        $data=str_replace("<","",$data);
        $data=str_replace(">","",$data);
        //$data=str_replace("/","",$data);
        $data=str_replace("?","",$data);
        //$data=str_replace("@","",$data);//邮箱验证使用
        //$data=str_replace(":","",$data);
        $data=str_replace("$","",$data);
        $data=str_replace(";","",$data);
        //$data=str_replace(",","",$data);
        $data=str_replace("&","",$data);
        $data=str_replace("*","",$data);
        //$data=str_replace("'","",$data);
        $data=str_replace("+","",$data);
        //$data=str_replace("-","",$data);
        $data=str_replace("=","",$data);
        //$data=str_replace("\"","",$data);*/
        /* $data=str_replace(" ","",$data);	//英文的空格
         $data=str_replace(" ","",$data);	//中文的空格
         $data=str_replace(" ","",$data);	//中文的空格*/
        //注意，此处不能过滤"|"，因数据库中多个值用"|"做分隔符；
        /*$data = trim($data);
        $data = stripslashes($data);*/
        //$data = htmlspecialchars($data);
        //$filterString = ["#","<",">","?",";","&","*","'","=","$","\"","src","SRC","eval(","EVAL(","script","SCRIPT","select","update","insert","delete"];
        $filterString = ["$","/*","*/","--","src","SRC","eval(","EVAL(","script","SCRIPT","version","VERSION","datadir","DATADIR",
            'union', 'select', 'insert', 'update', 'delete', 'drop',
            'create', 'alter', 'truncate', 'exec', 'execute', 'xp_',
            'load_file', 'outfile', 'dumpfile', 'into', 'from', 'where',
            'and', 'join', 'like', 'limit', 'order by', 'group by',
            'having', 'procedure', 'function', 'trigger', 'view', 'table',
            'database', 'schema', 'user', 'password', 'grant', 'revoke',
            'shutdown', 'kill', 'benchmark', 'sleep', 'waitfor', 'delay',
            'UNION', 'SELECT', 'INSERT', 'UPDATE', 'DELETE', 'DROP',
            'CREATE', 'ALTER', 'TRUNCATE', 'EXEC', 'EXECUTE', 'XP_',
            'LOAD_FILE', 'OUTFILE', 'DUMPFILE', 'INTO', 'FROM', 'WHERE',
            'AND',  'JOIN', 'LIKE', 'LIMIT', 'ORDER BY', 'GROUP BY',
            'HAVING', 'PROCEDURE', 'FUNCTION', 'TRIGGER', 'VIEW', 'TABLE',
            'DATABASE', 'SCHEMA', 'USER', 'PASSWORD', 'GRANT', 'REVOKE',
            'SHUTDOWN', 'KILL', 'BENCHMARK', 'SLEEP', 'WAITFOR', 'DELAY'];
        foreach ($filterString as $v){
            if (is_array($data)) {
                foreach ($data as $vv) {
                    if (count(explode($v, $vv)) > 1) Result::error("非法参数 $v");
                }
            } else {
                $data = $data ?? '';
                if (count(explode($v, $data)) > 1) Result::error("非法参数 $v");
            }
        }
        return $data;
    }
    /**
     * 请求头部信息 TODO
     * @return mixed|string
     */
    public static function getHttpHeader()
    {
        if (function_exists('apache_request_headers') && $result = apache_request_headers()) {
            $header = $result;
        } else {
            // 没有 apache_request_headers函数替代方法
            $header = [];
            $server = $_SERVER;
            foreach ($server as $key => $val) {
                if (0 === strpos($key, 'HTTP_')) {
                    $key = str_replace('_', '-', strtolower(substr($key, 5)));
                    $header[$key] = $val;
                }
            }
            if (isset($server['CONTENT_TYPE'])) {
                $header['content-type'] = $server['CONTENT_TYPE'];
            }
            if (isset($server['CONTENT_LENGTH'])) {
                $header['content-length'] = $server['CONTENT_LENGTH'];
            }
        }
        return $header;
    }
    /**
     * 列表转树形 TODO
     * @param array $list 列表数组
     * @param string $pk 主键名称
     * @param string $pid 父键名称
     * @param integer $root 根节点id
     * @param string $child 子节点名称
     * @return array
     */
    public static function list_to_tree($list = [], $pk = 'id', $pid = 'pid', $root = 0, $child = 'children')
    {
        $tree = [];
        $refer = [];
        foreach ($list as $k => $v) {
            $refer[$v[$pk]] = &$list[$k];
        }
        foreach ($list as $key => $val) {
            $parent_id = 0;
            if (isset($val[$pid])) {
                $parent_id = $val[$pid];
            }
            if ($root == $parent_id) {
                $tree[] = &$list[$key];
            } else {
                if (isset($refer[$parent_id])) {
                    $parent = &$refer[$parent_id];
                    $parent[$child][] = &$list[$key];
                }
            }
        }
        return $tree;
    }

    /**
     * 文件链接 TODO
     * @param array $file 文件信息
     * @return string
     */
    public static function fileUrl($file)
    {
        $file_url = '';
        if ($file) {
            if ($file['storage'] == 'local') {
                $file_url = self::file_url($file['file_path']);
            } else {
                $file_url = $file['domain'] . '/' . $file['file_path'];
                if (strpos($file_url, 'http') !== 0) {
                    $file_url = 'https://' . $file_url;
                }
            }
        }
        return $file_url;
    }

    /**
     * TODO 文件地址
     * 协议/域名/文件路径
     *
     * @param string $file_path 文件路径
     *
     * @return string
     */
    private static function file_url($file_path = '')
    {
        if (empty($file_path)) {
            return '';
        }

        if (strpos($file_path, 'http') !== false) {
            return $file_path;
        }

        $server_url = 'http://'.$_SERVER['HTTP_HOST'];

        if (stripos($file_path, '/') === 0) {
            $res = $server_url . $file_path;
        } else {
            $res = $server_url . '/' . $file_path;
        }

        return $res;
    }
    /**
     * 密码替换 TODO
     * @param $password
     * @return array|string|string[]
     */
    public static function passwordTh($passwords, $type = 1)
    {
        if ($type == 1) {
            return substr_replace($passwords, '$2y', 0, 3);
        }
        return substr_replace($passwords, '$2a', 0, 3);
    }
}